<script setup lang="ts">
import type { MessageInfo } from "@/api/message";
import { reactive, ref, onMounted, onBeforeUnmount, watch } from "vue";
import type {
  PlusPageInstance,
  ButtonsCallBackParams
} from "plus-pro-components";
import { ElMessageBox } from "element-plus";
import { Select, Delete } from "@element-plus/icons-vue";
import { emitter } from "@/utils/mitt";
import { message } from "@/utils/message";
import { buttons, tableColumns } from "./utils/hooks";
import $request, { tableEmptyText } from "./utils/request";

defineOptions({
  name: "MessagePage"
});

// 状态参数
const state = reactive({
  // 当前key
  currentRowKey: "",
  // 表格已选项
  selectedIds: []
});

// 当前选中数据
const currentRow = ref<MessageInfo>();

// 组件
const plusPageRef = ref<PlusPageInstance | null>();

// 表格事件操作（点击）
const handleTableAction = async (type: string) => {
  switch (type) {
    case "readAll":
      // 全部已读
      onRead(true);
      break;
    case "delete":
      // 批量删除
      onDelete(true);
      break;
    default:
  }
};

// 表格按钮操作（点击）
const handleTableOption = async ({ row, buttonRow }: ButtonsCallBackParams) => {
  currentRow.value = row as MessageInfo;
  switch (buttonRow.code) {
    case "read":
      // 已读/未读
      onRead(false);
      break;
    case "delete":
      // 删除
      onDelete(false);
      break;
  }
};

// 执行已读
const onRead = async (isBatch: boolean) => {
  if (isBatch) {
    await $request.put.readAll();
  } else {
    await $request.put.read(currentRow.value.id, !currentRow.value.isRead);
  }
  message("操作成功", { type: "success" });
  refresh();
};

// 表格选择
const handleTableSelect = (data: MessageInfo[]) => {
  state.selectedIds = [...data].map(item => item.id);
};

// 执行删除
const onDelete = async (isBatch: boolean) => {
  if (isBatch) {
    if (!state.selectedIds.length) {
      message("请选择数据！", { type: "warning" });
    } else {
      await ElMessageBox.confirm("确定删除所选数据", "提示");
      await $request.delete.batch(state.selectedIds);
    }
  } else {
    await $request.delete.remove(currentRow.value.id);
  }
  message("删除成功", { type: "success" });
  refresh();
};

// 刷新列表
const refresh = () => {
  plusPageRef.value?.getList();
};

onMounted(() => {
  emitter.on("messageClick", async ({ id, isRead }) => {
    if (!isRead) {
      await $request.put.read(id, true);
      refresh();
    }
  });
  emitter.on("messageReadAll", () => {
    refresh();
  });
});

onBeforeUnmount(() => {
  // 解绑公共事件，防止多次触发
  emitter.off("messageClick");
  emitter.off("messageReadAll");
});
</script>

<template>
  <div class="page-container">
    <plus-page
      ref="plusPageRef"
      :request="$request.get.list"
      :columns="tableColumns"
      :search="{
        showNumber: 2,
        labelWidth: '100px',
        colProps: {
          xs: 24,
          md: 12,
          lg: 8,
          xl: 6
        },
        labelPosition: 'right'
      }"
      :table="{
        hasIndexColumn: true,
        emptyText: tableEmptyText,
        isSelection: true,
        highlightCurrentRow: true,
        currentRowKey: state.currentRowKey,
        rowKey: 'id',
        actionBar: {
          showNumber: 4,
          buttons,
          width: 130,
          actionBarTableColumnProps: {
            align: 'center'
          }
        },
        adaptive: {
          offsetBottom: 32
        },
        onClickAction: handleTableOption,
        onSelectionChange: handleTableSelect
      }"
      :defaultPageInfo="{ page: 1, pageSize: 20 }"
      :defaultPageSizeList="[10, 20, 50, 100]"
    >
      <template #table-title>
        <el-row class="button-row">
          <el-button
            type="success"
            :icon="Select"
            plain
            @click="handleTableAction('readAll')"
          >
            全部已读
          </el-button>
          <el-button
            :icon="Delete"
            type="danger"
            plain
            :disabled="!state.selectedIds.length"
            @click="handleTableAction('delete')"
          >
            批量删除
          </el-button>
        </el-row>
      </template>
    </plus-page>
  </div>
</template>

<style lang="scss" scoped>
//
</style>
